package com.xz.bigsoubackend.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xz.bigsoubackend.common.ErrorCode;
import com.xz.bigsoubackend.datasource.*;
import com.xz.bigsoubackend.exception.BusinessException;
import com.xz.bigsoubackend.exception.ThrowUtils;
import com.xz.bigsoubackend.model.dto.search.SearchRequest;
import com.xz.bigsoubackend.model.entity.Picture;
import com.xz.bigsoubackend.model.enums.SearchTypeEnum;
import com.xz.bigsoubackend.model.vo.PostVO;
import com.xz.bigsoubackend.model.vo.SearchVO;
import com.xz.bigsoubackend.model.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;

/**
 * @author xuzhou
 * @version 1.0
 * @createTime 2024-11-10
 * @description 搜索 门面模式
 */
@Component
@Slf4j
public class SearchFacade {


    @Resource
    private PictureSearchDataSource pictureSearchDataSource;
    @Resource
    private UserSearchDataSource userSearchDataSource;
    @Resource
    private PostSearchDataSource postSearchDataSource;
    @Resource
    private SearchDataSourceRegistry searchDataSourceRegistry;

    public SearchVO searchAll(@RequestBody SearchRequest searchRequest, HttpServletRequest request) {
        String type = searchRequest.getType();

        if (!StringUtils.isBlank(type)) {
            SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
            ThrowUtils.throwIf(searchTypeEnum == null, ErrorCode.PARAMS_ERROR);
        }

        String searchText = searchRequest.getSearchText();
        long pageNum = searchRequest.getCurrent();
        long pageSize = searchRequest.getPageSize();
        // 如果 type 为空，那么就搜索出全部的数据
        if (type == null || type.isEmpty()) {
            CompletableFuture<Page<Picture>> pictureTask = CompletableFuture.supplyAsync(() -> {
                Page<Picture> picturePage = pictureSearchDataSource.doSearch(searchText, pageNum, pageSize);
                return picturePage;
            });

            CompletableFuture<Page<UserVO>> userTask = CompletableFuture.supplyAsync(() -> {
                Page<UserVO> userPage = userSearchDataSource.doSearch(searchText, pageNum, pageSize);
                return userPage;
            });

            CompletableFuture<Page<PostVO>> postTask = CompletableFuture.supplyAsync(() -> {
                Page<PostVO> postPage = postSearchDataSource.doSearch(searchText, pageNum, pageSize);
                return postPage;
            });

            CompletableFuture.allOf(userTask, postTask, pictureTask).join();

            try {
                Page<Picture> picturePage = pictureTask.get();
                Page<UserVO> userPage = userTask.get();
                Page<PostVO> postPage = postTask.get();
                SearchVO searchVO = new SearchVO();
                searchVO.setPictureList(picturePage.getRecords());
                searchVO.setUserList(userPage.getRecords());
                searchVO.setPostList(postPage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("查询异常", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询失败");
            }
        } else {
            SearchVO searchVO = new SearchVO();
            SearchDataSource<?> searchDataSource = searchDataSourceRegistry.getSearchDataSourceByType(type);
            Page<?> allPage = searchDataSource.doSearch(searchText, pageNum, pageSize);
            searchVO.setDataList(allPage.getRecords());
            return searchVO;
        }
    }
}
